using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;

namespace Ndo.Maths
{
    public abstract class Integer<TFinal> : Real<TFinal>, IModulus<TFinal>
        where TFinal : Integer<TFinal>, new()
    {
        protected Integer(){}
        public virtual TFinal Modulus(TFinal divisor)
        {
            return OperatorDelegates<TFinal>.Modulus(Self, divisor);
        }
        public virtual TFinal DivRem(TFinal divisor, out TFinal remainder)
        {
            remainder = Modulus(divisor);
            return DividedBy(divisor);
        }

        public static TFinal GCD(TFinal i1, TFinal i2)
        {
            if(i1.Sign == SignTypes.Positive && i2.Sign == SignTypes.Positive)
            {
                while(true)
                {
                    if (i1.GreaterThan(i2))
                    {
                        i1 = i1.Modulus(i2);
                        if (i1.Sign == SignTypes.Zero)
                            return i2;
                    }
                    else
                    {
                        i2 = i2.Modulus(i1);
                        if (i2.Sign == SignTypes.Zero)
                            return i1;
                    }
                }
            }
            return Number<TFinal>.Zero;
        }

        public static TFinal Power(TFinal x, TFinal y)
        {
            return Power<TFinal>(x, y);
        }
    }
}
